
Stage 3 開始啦~~來用個人履歷來嘗試 VitePress 的功能,先用 Figma 大概拉個畫面,然後就來開工吧~實際的完工畫面可以來這裡看看。
我們一開始先從最熟悉的功能往外擴展, VitePress 的 Markdown 可以把 .vue 檔塞進來用,我們就從這邊開始吧。
首先在 docs/pages/ 下面建立一個 resume-vue.md 的檔案,docs/components/template/ 下建立 resume.vue,然後在 nav.ts 中加入 resume-vue 的連結:
---
title: Opshell's Resume
author: 'Opshell'
layout: page
---
<script setup lang="ts">
    import TemplateResume from '@components/template/resume.vue';
</script>
<TemplateResume />
是的,要在 VitePress 的 Markdown 中使用 Vue 就是這麼簡單,因為在 VitePress 中,每個 Markdown 都會被編譯成 HTML 然後當作 Vue SFC 處理。
簡單的說,在 VitePress 中 可以使用任何 Vue 的功能,包括動態模板、script 和 import Vue Component。
也就是說,你可以把 .md 當作比較特別的 Vue SFC 使用。
SSR 相容性
所有的 Vue 用法都需要 相容 SSR,請參考SSR 兼容性,得到更多資訊和常見問題的解決方案。
咦奇怪? 不是昨天才說可以自動 import component 了嗎? 為什麼這邊不加 import 的 script 會沒東西呢?
爬了一下文件,原來少了這行參數:
import Components from 'unplugin-vue-components/vite';
export default defineConfig({
    vite: {
        plugins: [
            Components({
                dirs: ['./components'], // 指定components位置 預設是'src/components'
                dts: './types/components.d.ts', // .d.ts生成位置
                extensions: ['vue'],
                include: [/\.vue$/, /\.vue\?vue/, /\.md$/], // allow auto import and register components used in markdown // [!code ++]
                directoryAsNamespace: true, // 允許子目錄作為命名空間
                resolvers: [] // 解析規則
            })
        ]
    }
});
include 是在決定,auto import 的 component 可以用在哪,加入了 /\.md$/ 後就可以不用宣告囉~
<script setup lang="ts">
</script>
<template>
    <article class="article-block">
        <div class="left-block" />
        <hr class="divider" />
        <div class="right-block" />
    </article>
</template>
<style lang="scss">
</style>
就從左上切版到右下吧,left-block 區塊中加入大頭照區塊,
<header class="header-block">
    <div class="image-box">
        <img src="/images/resume/portrait.png" alt="Opshell 大頭貼" />
    </div>
    <h1 class="name">
        <span class="en">{{ frontmatter.name }}</span>
    </h1>
    <span class="job-title">
        {{ frontmatter.jobTitle }}
    </span>
    <div class="mbti" />
</header>
要塞圖片進來,我們就來研究一下 VitePress 的兩種資源處理方式吧,
向前面說的,所有的 .md 都會變成 vue 給 vite 處理,所以可以用絕對或相對路徑的方式引用靜態資源(下面為相對路徑在各種情境下的引用方式):

<img src="/images/resume/portrait.png" alt="Opshell 大頭貼" />
.mbti {
    background: url('/images/resume/mbti.png') no-repeat 50% 50%;
}
而相對路徑引用的出發點是 docs/ 下面,所以記得在 docs/ 目錄下面建立一個 images 目錄。
所有引用的資源(絕對或相對都是),都會在 build 的時候被複製到 dist 目錄中,然後重新命名為 hash 格式,沒被使用到的資源則會被忽略。
小於 4kb 的圖片會被轉換成 base64 內聯,這個行為可以通過修改 Vite.build.assetsInlineLimit 設定來調整。
連結引用進來的文件不會被當作資源
在.md中,通過連結引用的 PDF 或其他文件,不會自動被當作是資源,要讓這些文件可以用,必須手動放在public目錄裡面。
有時可能需要一些靜態資源,但這些資源沒有直接被 .md 或 Vue 直接引用,或想以原始檔名提供文件,像 robots.txt,favicons 和 PWA icon 等。
可以將這些文件放置在源目錄的 public 目錄中。例如,如果項目根目錄是 ./docs,並且使用默認源目錄位置,那麼 public 目錄將是 ./docs/public。
放置在 public 中的資源將按原樣複製到輸出目錄的根目錄中。
注意
應使用根絕對路徑來引用放置在public中的文件——例如,public/icon.png會是這樣引用/icon.png。
也就是說 Opshell 上面的範例,也可以是放在docs/public/images中,區別在於打包輸出的方式。
而 Opshell 統一都放在public裡,打算找個時間來研究一下,兩中輸出方式主要的差異在哪。
在前面的Day09 - 部署到 Github Page有提過,如果專案沒有部署在 Base url 上面的時候,會需要在 config 中設定 base 選項,
這個情況下,所有的靜態資源 build 時會自動修正路徑來契合 base 選項,例:如果 .md 中有一個對 public 中的資源的引用

上面的情況下,調整 base 值不用調整路徑。
如果是一個 Vue Component ,動態的引用資源:
<img :src="theme.logoPath" />
這種情況下, VitePress 提供了 withBase 來 handle 路徑, withBase 會把 base 的值追加在資源的 url 中:
<script setup>
    import { useData, withBase } from 'vitepress';
    const { theme } = useData();
</script>
<template>
    <img :src="withBase(theme.logoPath)" />
</template>
今天學資源引用,感覺 VitePress 各種使用情境都注意到了,和平常的 vue vite 專案使用上也沒什麼差異,真的是個很容易上手的部落格框架。